package com.amarsoft.apot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class ThreadPoolTaskConfig {


	public static Integer taskTableExecutorSize = 50;

	private static Integer taskCompareExecutor = 10;

	private static Integer completeSyncScheduledExecutor = 20;

	private static Integer runTimeSyncScheduledExecutor = 20;

	public Integer getRunTimeSyncScheduledExecutor() {
		return runTimeSyncScheduledExecutor;
	}

	public void setRunTimeSyncScheduledExecutor(Integer runTimeSyncScheduledExecutor) {
		this.runTimeSyncScheduledExecutor = runTimeSyncScheduledExecutor;
	}

	@Bean(name = "coreSyncExecutor")
	public ThreadPoolTaskExecutor coreSyncExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(1);
		taskExecutor.setMaxPoolSize(1);
		taskExecutor.setQueueCapacity(5);
		taskExecutor.setThreadNamePrefix("coreSyncExecutor");
		return taskExecutor;
	}

	@Bean(name = "runCoreSyncExecutor")
	public ThreadPoolExecutor runCoreSyncExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				10,
				10,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(10),
				new ThreadPoolExecutor.DiscardPolicy());
		return threadPoolExecutor;
	}


	@Bean(name = "coreMigrationExecutor")
	public ThreadPoolTaskExecutor coreMigrationExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(1);
		taskExecutor.setMaxPoolSize(1);
		taskExecutor.setQueueCapacity(5);
		taskExecutor.setThreadNamePrefix("coreMigrationExecutor");
		return taskExecutor;
	}

	@Bean(name = "dataSyncExecutor")
	public ThreadPoolExecutor dataSyncExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				taskTableExecutorSize,
				taskTableExecutorSize,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(50000),
				new ThreadPoolExecutor.DiscardOldestPolicy());
		return threadPoolExecutor;
	}

	@Bean(name = "listenerSyncExecutor")
	public ThreadPoolExecutor listenerSyncExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				20,
				20,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(50000),
				new ThreadPoolExecutor.DiscardOldestPolicy());
		return threadPoolExecutor;
	}

	@Bean(name = "completeSyncScheduledExecutor")
	public ThreadPoolExecutor completeSyncScheduledExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				completeSyncScheduledExecutor,
				completeSyncScheduledExecutor,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(500),
				new ThreadPoolExecutor.CallerRunsPolicy());
		return threadPoolExecutor;
	}

	@Bean(name = "runTimeSyncScheduledExecutor")
	public ThreadPoolExecutor runTimeSyncScheduledExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				runTimeSyncScheduledExecutor,
				runTimeSyncScheduledExecutor,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(500),
				new ThreadPoolExecutor.CallerRunsPolicy());
		return threadPoolExecutor;
	}

	@Bean(name = "completeSyncExecutor")
	public ThreadPoolTaskExecutor completeSyncExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(20);
		taskExecutor.setMaxPoolSize(20);
		taskExecutor.setQueueCapacity(5000);
		taskExecutor.setThreadNamePrefix("completeSyncExecutor");
		return taskExecutor;
	}

	@Bean(name = "taskCompareExecutor")
	public ThreadPoolExecutor taskCompareExecutor() {
		ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
				2,
				3,
				10,
				TimeUnit.MICROSECONDS,
				new LinkedBlockingQueue<>(5),
				new ThreadPoolExecutor.DiscardOldestPolicy());
		return threadPoolExecutor;
	}

	@Bean(name = "taskMigrationExecutor")
	public ThreadPoolTaskExecutor taskMigrationExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(taskCompareExecutor);
		taskExecutor.setMaxPoolSize(taskCompareExecutor);
		taskExecutor.setQueueCapacity(50000);
		taskExecutor.setThreadNamePrefix("taskMigrationExecutor");
		return taskExecutor;
	}

}
